﻿//此程序作用：访问特定文件的数字签名信息
//包括：数字签名拥有者姓名、颁发单位、颁布时间等
//例如：访问C:\Program Files (x86)\Microsoft Office\root\Office16\MSPUB.EXE 的数字证书

#ifndef UNICODE
#define UNICODE
#endif

#ifndef _UNICODE
#define _UNICODE
#endif

#define _WIN32_WINNT 0x0500
#define WINVER       0x0500

#include <windows.h>
#include <Softpub.h>
#include <Wincrypt.h>
#include <tchar.h>
#include <stdlib.h>

#pragma comment(lib, "Crypt32.lib")
#pragma comment(lib, "Wintrust.lib")

LPTSTR GetCertificateDescription(PCCERT_CONTEXT pCertCtx)
{
	DWORD dwStrType;
	DWORD dwCount;
	LPTSTR szSubjectRDN = NULL;

	dwStrType = CERT_X500_NAME_STR;
	dwCount = CertGetNameString(pCertCtx,
		CERT_NAME_RDN_TYPE,
		0,
		&dwStrType,
		NULL,
		0);
	if (dwCount)
	{
		szSubjectRDN = (LPTSTR)LocalAlloc(0, dwCount * sizeof(TCHAR));
		CertGetNameString(pCertCtx,
			CERT_NAME_RDN_TYPE,
			0,
			&dwStrType,
			szSubjectRDN,
			dwCount);
	}

	return szSubjectRDN;
}


int main ()
{
	// 目标：查看 C:\Program Files (x86)\Microsoft Office\root\Office16\MSPUB.EXE 的数字证书
	GUID guidAction = WINTRUST_ACTION_GENERIC_VERIFY_V2;
	WINTRUST_FILE_INFO sWintrustFileInfo;
	WINTRUST_DATA      sWintrustData;
	HRESULT            hr;


	memset((void*)&sWintrustFileInfo, 0x00, sizeof(WINTRUST_FILE_INFO));
	memset((void*)&sWintrustData, 0x00, sizeof(WINTRUST_DATA));

	sWintrustFileInfo.cbStruct = sizeof(WINTRUST_FILE_INFO);

	//只修改这里即可
	sWintrustFileInfo.pcwszFilePath = L"C:\\Program Files (x86)\\Microsoft Office\\root\\Office16\\MSPUB.EXE";
	sWintrustFileInfo.hFile = NULL;

	sWintrustData.cbStruct = sizeof(WINTRUST_DATA);
	sWintrustData.dwUIChoice = WTD_UI_NONE;
	sWintrustData.fdwRevocationChecks = WTD_REVOKE_NONE;
	sWintrustData.dwUnionChoice = WTD_CHOICE_FILE;
	sWintrustData.pFile = &sWintrustFileInfo;
	sWintrustData.dwStateAction = WTD_STATEACTION_VERIFY;

	hr = WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &guidAction, &sWintrustData);

	if (TRUST_E_NOSIGNATURE == hr)
	{
		_tprintf(_T("No signature found on the file.\n"));
	}
	else if (TRUST_E_BAD_DIGEST == hr)
	{
		_tprintf(_T("The signature of the file is invalid\n"));
	}
	else if (TRUST_E_PROVIDER_UNKNOWN == hr)
	{
		_tprintf(_T("No trust provider on this machine can verify this type of files.\n"));
	}
	else if (S_OK != hr)
	{
		_tprintf(_T("WinVerifyTrust failed with error 0x%.8X\n"), hr);
	}
	else
	{
		_tprintf(_T("File signature is OK.\n"));

		// retreive the signer certificate and display its information
		CRYPT_PROVIDER_DATA const *psProvData = NULL;
		CRYPT_PROVIDER_SGNR       *psProvSigner = NULL;
		CRYPT_PROVIDER_CERT       *psProvCert = NULL;
		FILETIME                   localFt;
		SYSTEMTIME                 sysTime;

		psProvData = WTHelperProvDataFromStateData(sWintrustData.hWVTStateData);
		if (psProvData)
		{
			psProvSigner = WTHelperGetProvSignerFromChain((PCRYPT_PROVIDER_DATA)psProvData, 0, FALSE, 0);
			if (psProvSigner)
			{
				FileTimeToLocalFileTime(&psProvSigner->sftVerifyAsOf, &localFt);
				FileTimeToSystemTime(&localFt, &sysTime);

				_tprintf(_T("Signature Date = %.2d/%.2d/%.4d at %.2d:%2.d:%.2d\n"), sysTime.wDay, sysTime.wMonth, sysTime.wYear, sysTime.wHour, sysTime.wMinute, sysTime.wSecond);

				psProvCert = WTHelperGetProvCertFromChain(psProvSigner, 0);
				if (psProvCert)
				{
					LPTSTR szCertDesc = GetCertificateDescription(psProvCert->pCert);
					if (szCertDesc)
					{
						_tprintf(_T("File Signer = %s\n"), szCertDesc);
						LocalFree(szCertDesc);
					}
				}

				if (psProvSigner->csCounterSigners)
				{
					_tprintf(_T("\n"));
					// Timestamp information
					FileTimeToLocalFileTime(&psProvSigner->pasCounterSigners[0].sftVerifyAsOf, &localFt);
					FileTimeToSystemTime(&localFt, &sysTime);

					_tprintf(_T("Timestamp Date = %.2d/%.2d/%.4d at %.2d:%2.d:%.2d\n"), sysTime.wDay, sysTime.wMonth, sysTime.wYear, sysTime.wHour, sysTime.wMinute, sysTime.wSecond);
					psProvCert = WTHelperGetProvCertFromChain(&psProvSigner->pasCounterSigners[0], 0);
					if (psProvCert)
					{
						LPTSTR szCertDesc = GetCertificateDescription(psProvCert->pCert);
						if (szCertDesc)
						{
							_tprintf(_T("Timestamp Signer = %s\n"), szCertDesc);
							LocalFree(szCertDesc);
						}
					}
				}
			}
		}
	}

	sWintrustData.dwUIChoice = WTD_UI_NONE;
	sWintrustData.dwStateAction = WTD_STATEACTION_CLOSE;
	WinVerifyTrust((HWND)INVALID_HANDLE_VALUE, &guidAction, &sWintrustData);

	return 0;
}
